import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // home: ScrollControllerTestRoute(),
      home: const MyHomePage(
        title: 'demo',
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: Column(
        children: const <Widget>[
          ListTile(title: Text("商品列表")),
          Expanded(
            child: PageWidget(),
          ),
        ],
      ),
    );
  }
}

// 如果要实现页面切换和 Tab 布局，我们可以使用 PageView 组件。需要注意，PageView 是一个非常重要的组件，因为在移动端开发中很常用，比如大多数 App 都包含 Tab 换页效果、图片轮动以及抖音上下滑页切换视频功能等等，这些都可以通过 PageView 轻松实现。
// PageView({
//   Key? key,
//   this.scrollDirection = Axis.horizontal, // 滑动方向
//   this.reverse = false,
//   PageController? controller,
//   this.physics,
//   List<Widget> children = const <Widget>[],
//   this.onPageChanged,

//   //每次滑动是否强制切换整个页面，如果为false，则会根据实际的滑动距离显示页面
//   this.pageSnapping = true,
//   //主要是配合辅助功能用的，后面解释
//   this.allowImplicitScrolling = false,
//   //后面解释
//   this.padEnds = true,
// })

class PageWidget extends StatelessWidget {
  const PageWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var children = <Widget>[];
    // 生成 6 个 Tab 页
    for (int i = 0; i < 6; i++) {
      children.add(Page(text: '$i'));
      // children.add(KeepAliveWrapper(child:Page( text: '$i')); // 使用缓存组件包装
    }

    return PageView(
      scrollDirection: Axis.vertical, // 滑动方向为垂直方向
      allowImplicitScrolling: true, // 允许滑动到页面外部, 为 true 时会缓存前后各一页
      children: children,
    );
  }
}


class Page extends StatefulWidget {
  const Page({Key? key, required this.text}) : super(key: key);

  final String text;

  @override
  _PageState createState() => _PageState();
}


// 混入 AutomaticKeepAliveClientMixin 实现缓存页面
class _PageState extends State<Page> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true; // 是否需要缓存

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用
    print("build ${widget.text}");
    return Center(child: Text(widget.text, textScaleFactor: 5));
  }
}


// 封装缓存组件，如果哪个列表项需要缓存，只需要使用 KeepAliveWrapper 包裹一下它即可。

// KeepAliveWrapper(
//   // 为 true 后会缓存所有的列表项，列表项将不会销毁。
//   // 为 false 时，列表项滑出预加载区域后将会别销毁。
//   // 使用时一定要注意是否必要，因为对所有列表项都缓存的会导致更多的内存消耗
//   keepAlive: true,
//   child: ListItem(index: index),
// );
class KeepAliveWrapper extends StatefulWidget {
  const KeepAliveWrapper({
    Key? key,
    this.keepAlive = true,
    required this.child,
  }) : super(key: key);
  final bool keepAlive;
  final Widget child;

  @override
  _KeepAliveWrapperState createState() => _KeepAliveWrapperState();
}

class _KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
    if (oldWidget.keepAlive != widget.keepAlive) {
      // keepAlive 状态需要更新，实现在 AutomaticKeepAliveClientMixin 中
      updateKeepAlive();
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  bool get wantKeepAlive => widget.keepAlive;
}
